@echo off
:: 设置cmd窗口标题和主题
call lib\theme "%~1 - %~2 - %~3"

:: 环境标识 UAT、PRE 等
set ENV=%1
:: 模块名称 
set MODULE_NAME=%2
:: 远程服务器IP地址
set HOST=%3
:: 远程服务器登录用户名
set USER=%4
:: 远程服务器登录密码
set PSW=%5
:: 远程服务器基础目录（远程执行的linux命令都是相对这个目录而言的）
set REMOTE_DIR=%6
:: 待上传jar包全名，如果是PC前端代码，则对应的是dist文件夹名称
set JAR_FILE_NAME=%7
:: 本地工作目录（非本bat文件所在的目录）
set WORK_PATH=%8
:: 由调用方提供一个随机数
set RANDOM_NUM=%9
:: 本地待上传的文件或文件夹的完整路径
set LOCAL_FILE=%WORK_PATH%\build\%JAR_FILE_NAME%
:: 待上传到远程服务器的shell脚本，只有发布jar包时会用到，对于PC前端代码的发布不涉及这个脚本
set UPDATE_SH=%WORK_PATH%/lib/deploy.sh

::日志模块（不同的模块分成不同的日志文件）
set LOG_MODULE=%ENV%_%MODULE_NAME%_UPDATE_%HOST%

set HOUR=%TIME:~0,2%
:: 小时可能是12小时制，如果小时数字小于10就将数字前的一个空格替换成0
if %HOUR% lss 10 (set HOUR=0%HOUR:~1,2%)
set DATE_TIME=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%%HOUR%%TIME:~3,2%%TIME:~6,2%
:: 临时日志文件
set TEMP_LOG=logs\temp\%DATE_TIME%_%RANDOM_NUM%.log
call lib\tryMkdir logs\temp\

call print\info %LOG_MODULE% "============= BEGIN UPDATE ============="
call print\info %LOG_MODULE% ""
call print\info %LOG_MODULE% "    ENV: %ENV%"
call print\info %LOG_MODULE% "    MODULE_NAME: %MODULE_NAME%"
call print\info %LOG_MODULE% "    REMOTE_HOST: %HOST%"
call print\info %LOG_MODULE% "    LOCAL_WORK_PATH: %WORK_PATH%"
call print\info %LOG_MODULE% "    LOCAL_FILE: %LOCAL_FILE%"
call print\info %LOG_MODULE% "    REMOTE_WORK_DIR: %REMOTE_DIR%"
call print\info %LOG_MODULE% "    JAR_FILE_NAME: %JAR_FILE_NAME%"
call print\info %LOG_MODULE% ""                                              
call print\info %LOG_MODULE% "----------------------------------------"               
call print\info %LOG_MODULE% ""

:: 检查本地待上传的文件或文件夹是否存在
if exist %LOCAL_FILE% (
  call print\info %LOG_MODULE% "[CHECK] %JAR_FILE_NAME% is ready."
) else (
  call print\error %LOG_MODULE% "[CHECK] error: please provide the %JAR_FILE_NAME% in %LOCAL_FILE%"
  call print\info %LOG_MODULE% ""                                              
  call print\info %LOG_MODULE% "================= END =================="               
  call print\info %LOG_MODULE% "" 
  pause
  exit /b
)

:: 判断是要发布PC前端代码，还是发布jar包，执行不同的操作
if "%MODULE_NAME%" equ "PC" (
  :: 发布PC前端代码前，先将远程服务器中对应的代码移除
  call print\info %LOG_MODULE% "[REMOTE_COMMAND] try remove static codes if exist..."
  echo | lib\plink -pw %PSW% %USER%@%HOST% "rm %REMOTE_DIR%/*.js*; rm %REMOTE_DIR%/*.html; rm -r %REMOTE_DIR%/static/;"
  call print\info %LOG_MODULE% "[REMOTE_COMMAND] removed"
  
  
  call print\info %LOG_MODULE% "[UPLOADING] uploading static codes to remote..."
  :: 调用pscp执行文件夹的上传操作
  lib\pscp -q -r -pw %PSW% -scp %LOCAL_FILE%\* %USER%@%HOST%:%REMOTE_DIR%/
  :: errorlevel 是bat批处理内置变量，表示上一条命令执行是否成功 0：成功 其他非0值表示失败
  if %errorlevel% equ 0 (
    call print\info %LOG_MODULE% "[UPLOADING] upload successful."
  ) else (
    call print\error %LOG_MODULE% "[UPLOADING] upload failed."
    call print\info %LOG_MODULE% ""                                              
    call print\info %LOG_MODULE% "================= END =================="              
    call print\info %LOG_MODULE% "" 
    pause
    exit /b
  )
) else (
  :: 发布jar包前，先将最新的 deploy.sh 脚本上传到 远程linux服务器的基础目录中
  call print\info %LOG_MODULE% "[UPLOADING] uploading deploy.sh to remote..."
  lib\pscp -q -pw %PSW% -scp %UPDATE_SH% %USER%@%HOST%:%REMOTE_DIR%/
  :: errorlevel 是bat批处理内置变量，表示上一条命令执行是否成功 0：成功 其他非0值表示失败
  if %errorlevel% neq 0 (
    call print\error %LOG_MODULE% "[UPLOADING] uploading failed."
    call print\info %LOG_MODULE% ""                                              
    call print\info %LOG_MODULE% "================= END =================="               
    call print\info %LOG_MODULE% "" 
    pause
    exit /b
  )
  call print\info %LOG_MODULE% "[UPLOADING] uploading successful."
  
  :: 为刚上传成功的deploy.sh文件添加可执行的权限
  call print\info %LOG_MODULE% "[REMOTE_COMMAND] chmod u+x deploy.sh."
  echo | lib\plink -pw %PSW% %USER%@%HOST% "cd %REMOTE_DIR%;chmod u+x deploy.sh;"

  :: 尝试在远程服务器上创建必要的文件夹，其中 build 文件夹用于存放待上传发布的新jar包，beckup 文件夹用于存放旧jar包备份
  call print\info %LOG_MODULE% "[REMOTE_COMMAND] try mkdir if need.
  echo | lib\plink -pw %PSW% %USER%@%HOST% "mkdir -p %REMOTE_DIR%/build; mkdir -p %REMOTE_DIR%/backup;"

  :: 上传jar包到远程服务器的build文件夹内
  call print\info %LOG_MODULE% "[UPLOADING] uploading %JAR_FILE_NAME% to remote..."
  lib\pscp -q -pw %PSW% -scp %LOCAL_FILE% %USER%@%HOST%:%REMOTE_DIR%/build/
  :: errorlevel 是bat批处理内置变量，表示上一条命令执行是否成功 0：成功 其他非0值表示失败
  if "%errorlevel%" neq "0" (
    call print\error %LOG_MODULE% "[UPLOADING] upload failed."
    call print\info %LOG_MODULE% ""                                              
    call print\info %LOG_MODULE% "================= END =================="             
    call print\info %LOG_MODULE% ""  
    pause
    exit /b
  )

  call print\info %LOG_MODULE% "[UPLOADING] upload successful."
  call print\info %LOG_MODULE% "[DEPLOY] deploy..."

  :: 通过 plink 工具 远程调用并执行服务器中的 deploy.sh 脚本，使其自行完成发布升级过程，plink命令返回的日志会输出到临时文件中
  lib\plink -batch -pw %PSW% %USER%@%HOST% "cd %REMOTE_DIR%;./deploy.sh update  %JAR_FILE_NAME%" >> %TEMP_LOG%

  :: 从临时文件中读取内容并将每行内容以正常日志输出到屏幕和日志文件
  for /f  "tokens=*" %%H in (%TEMP_LOG%) do (
    :: 打印临时文件中的每一行
    call print\info %LOG_MODULE% "%%H"
  )
  del %TEMP_LOG%
)

call print\info %LOG_MODULE% "[DEPLOY] deploy finish."
call print\info %LOG_MODULE% ""                                              
call print\info %LOG_MODULE% "================= END =================="           
call print\info %LOG_MODULE% "" 

:: 若干秒之后会自动关闭窗口
timeout /t 60
exit /b 0



